#pragma once

#ifndef __CORE_LogMgr_H__
#define __CORE_LogMgr_H__

#include "FLOW_core/namespace.h"
#include "FLOW_core/log_type.h"

#define LOG_MGR	CORE::CLogMgr::GetInstance( )

#ifndef _FINAL
#define LOG( ae_log_type, apsz_subsystem, apsz_log_msg, ... ) LOG_MGR->OutputLogMsg( ae_log_type, apsz_subsystem, apsz_log_msg, __VA_ARGS__ )
#else
#define LOG( ae_log_type, apsz_sybsystem, apsz_log_msg, ... )
#endif

namespace CORE
{
	class ILogger;

	/*!
	 * \brief Singleton manager to log messages to different sinks like Files, standard output, network, etc...
	 *
	 * Singleton manager to log messages to different sinks like Files, standard output, network, etc...
	 */
	class CLogMgr
	{
	private:
		//============================== DATA MEMBERS =========================

		//! Array of different loggers that implements the different logics to output to different media
		CVector< ILogger* >			m_v_logger;

		//! Boolean that tells if the manager has been initialized
		bool_t						m_b_initialized;

		//! Boolean that tells if the manager has been destroyed
		bool_t						m_b_destroyed;

		//! Reference to the unique instance of the manager
		static CLogMgr*				sg_p_log_mgr;

	protected:

		//================================= METHODS ===========================

		//! Output a message passing the log type, subsystem, message and a list of args
		bool_t OutputLogMsgToLoggers( LOG_TYPE ae_log_type, const char_t* apsz_subsystem, const char_t* apsz_log_msg );

	public:
		//================================= METHODS ===========================

		//! Default constructor
		CLogMgr( );

		//! Destructor
		~CLogMgr( );

		//! Initializes the Log Manager with the basic loggers specified
		bool_t Initialize( void );

		//! Shutdowns the manager, no more logs will be output
		bool_t Shutdown( void );

		//! Returns the unique instance of the manager
		static CLogMgr* GetInstance( void );

		//! Registers a new logger
		bool_t RegisterLogger( ILogger* ap_logger );

		//! Unregister a logger
		bool_t UnregisterLogger( ILogger* ap_logger );

		//! Output a message specifying its type, subsystem and adding a formatted message
		bool_t OutputLogMsg( LOG_TYPE ae_log_type, const char_t* apsz_subsystem, const char_t* apsz_log_msg, ... );

		//! Formats message using a standard method and stores it in ar_str_log_msg
		static void FormatMsg( LOG_TYPE ae_log_type, const char_t* apsz_subsystem, const char_t* apsz_log_msg, CString& ar_str_log_msg );
	};

} // namespace CORE

#endif